package wangxiaotao.utils;

import lombok.extern.slf4j.Slf4j;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.AesKeyStrength;
import net.lingala.zip4j.model.enums.CompressionMethod;
import net.lingala.zip4j.model.enums.EncryptionMethod;

import java.io.File;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * zip加密解密工具类
 */
@Slf4j
public class ZipUtil {

    private ZipUtil(){}

    /** 默认加密密码） */
    private static final String DEFAULT_PASSWORD = "123456";
    /** 默认不使用任何压缩（称为 STORE 压缩） */
    private static final CompressionMethod DEFAULT_COMPRESSION_METHOD = CompressionMethod.STORE;
    /** 默认加密方式 */
    private static final EncryptionMethod DEFAULT_ENCRYPTION_METHOD = EncryptionMethod.AES;
    /** 默认加密密钥长度 */
    private static final AesKeyStrength DEFAULT_AESKEY_STRENGTH = AesKeyStrength.KEY_STRENGTH_256;

    //密钥 文件 路径 接收路径 传出路径

    /**
     * 创建zip压缩包
     * @param method 压缩方式
     * @param encryptionMethod 加密方式
     * @param aesKeyStrength 密钥长度
     * @param password   加密密码
     * @param outFileName 输出文件名称
     * @param inAbsoluteFileNames 需要加密的文件
     * @throws Exception
     */
    public static void createZip(CompressionMethod method,
                                 EncryptionMethod encryptionMethod,
                                 AesKeyStrength aesKeyStrength,
                                 char[] password,
                                 String outFileName,
                                 String ...inAbsoluteFileNames) throws Exception {
        ZipParameters zipParameters = buildZipParameters(method, encryptionMethod, aesKeyStrength);
        //文件名转file
        List<File> files = Arrays.stream(inAbsoluteFileNames).map(File::new).collect(Collectors.toList());
        ZipFile zipFile = new ZipFile(outFileName, password);
        try {
            zipFile.addFiles(files, zipParameters);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new Exception(e.getMessage());
        }
    }

    /**
     *
     * 创建zip压缩包
     * @param method 压缩方式
     * @param encryptionMethod 加密方式
     * @param aesKeyStrength 密钥长度
     * @param password   加密密码
     * @param outFileName 输出文件名称
     * @param is 文件流
     * @throws Exception
     */
    public static void createZip(CompressionMethod method,
                                 EncryptionMethod encryptionMethod,
                                 AesKeyStrength aesKeyStrength,
                                 char[] password,
                                 String outFileName,
                                 InputStream is) throws Exception {
        ZipParameters zipParameters = buildZipParameters(method, encryptionMethod, aesKeyStrength);
        ZipFile zipFile = new ZipFile(outFileName, password);
        try {
            zipFile.addStream(is,zipParameters);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new Exception(e.getMessage());
        }
    }

    /**
     * 创建zip压缩包
     * @param password 加密密码
     * @param outFileName 输出文件
     * @param inAbsoluteFileNames 输入文件
     * @throws Exception
     */
    public static void createZip(char[] password,
                                 String outFileName,
                                 String ...inAbsoluteFileNames) throws Exception {
        createZip(DEFAULT_COMPRESSION_METHOD,
                DEFAULT_ENCRYPTION_METHOD,
                DEFAULT_AESKEY_STRENGTH,
                password, outFileName,inAbsoluteFileNames);
    }


    /**
     * 创建zip压缩包
     * @param outFileName 输出文件
     * @param inAbsoluteFileNames 输入文件
     * @throws Exception
     */
    public static void createZip(String outFileName,
                                 String ...inAbsoluteFileNames) throws Exception {
        createZip(DEFAULT_PASSWORD.toCharArray(), outFileName,inAbsoluteFileNames);
    }

    /**
     * 解压zip压缩包
     * @param password 解压密码
     * @param outPutDirectory  输出
     * @param zipName 压缩包文件
     * @throws Exception
     */
    public static void createUnzip(char[] password,String outPutDirectory, String zipName) throws Exception {
        try {
            new ZipFile(zipName,password).extractAll(outPutDirectory);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new Exception(e.getMessage());
        }
    }

    /**
     * 解压zip压缩包
     * @param outPutDirectory  输出
     * @param zipName 压缩包文件
     * @throws Exception
     */
    public static void createUnzip(String outPutDirectory, String zipName) throws Exception {
       createUnzip(DEFAULT_PASSWORD.toCharArray(),outPutDirectory,zipName);
    }







    /**
     * 设置加密参数
     * @param method 压缩方式
     * @param encryptionMethod 加密方式
     * @param aesKeyStrength 密钥长度
     * @return
     */
    private static ZipParameters buildZipParameters(CompressionMethod method, EncryptionMethod encryptionMethod, AesKeyStrength aesKeyStrength){
        ZipParameters zipParameters = new ZipParameters();
        //压缩参数设置
        zipParameters.setCompressionMethod(method);
        //加密设置
        zipParameters.setEncryptFiles(true);
        //加密方式
        zipParameters.setEncryptionMethod(encryptionMethod);
        zipParameters.setAesKeyStrength(aesKeyStrength);
        return  zipParameters;
    }

}